#! python3
# -*- coding: utf-8 -
'''
Created on 2020年05月10日
@author: zxyong 13738196011
'''

import binascii,snap7,struct
from com.zxy.common import Com_Para
from com.zxy.common.Com_Fun import Com_Fun
import modbus_tk.defines as cst
import modbus_tk.modbus_rtu as modbus_rtu
import modbus_tk.modbus_tcp as modbus_tcp
from com.zxy.adminlog.UsAdmin_Log import UsAdmin_Log
from com.plugins.A01_N86TYV import A01_Para
class A01_N86TYV_PLC(object):
    def __init__(self):
        pass
    def open_plc(self,inputPLCrack,inputPLCslot):
        try:
            if A01_Para.objPLC_tcp is None:
                A01_Para.objPLC_tcp = snap7.client.Client()
            if A01_Para.objPLC_tcp.get_connected() == False :
                A01_Para.objPLC_tcp.connect(A01_Para.objPLC_addr,inputPLCrack, inputPLCslot,tcpport=A01_Para.objPLC_Port)
                print("plc 2 connect ok"+" "+Com_Fun.GetTimeDef())
            return True 
        except Exception as exc:
            uL = UsAdmin_Log(Com_Para.ApplicationPath, "A01_N86TYV_PLC.open_plc error:"+repr(exc))
            uL.WriteLog()
            print("plc 2 connect error"+repr(exc)+" "+Com_Fun.GetTimeDef())
            A01_Para.objPLC_tcp = None
            return False 
    def get_data_plc(self,inputPLCrack,inputPLCslot,inputDb_number,inputStart,inputSize):
        red = None
        try:
            if self.open_plc(inputPLCrack,inputPLCslot) == True:
                red= A01_Para.objPLC_tcp.db_read(inputDb_number,inputStart,inputSize)
            return red
        except Exception as exc:
            uL = UsAdmin_Log(Com_Para.ApplicationPath, "A01_N86TYV_PLC.get_data_plc error:"+repr(exc))
            uL.WriteLog()
            return red
    def get_dint(self,bytearray_, byte_index):
        data = bytearray_[byte_index:byte_index + 4]    
        data[1] = data[1] & 0xff    
        data[0] = data[0] & 0xff    
        packed = struct.pack('4B', *data)    
        value = struct.unpack('>i', packed)[0]    
        return value
    def single_signal_read(self,inputplc_addr_element): 
        try:
            if A01_Para.objPLC_tcp is None or inputplc_addr_element is None:
                return None       
            data_type = inputplc_addr_element.attdata_type
            data_area = inputplc_addr_element.attdata_area
            db_num  = inputplc_addr_element.attdb_num
            address = inputplc_addr_element.attaddress
            if data_area == 'M':
                offset = int(address.split('.')[0])
                if data_type == 'Int':
                    data = A01_Para.objPLC_tcp.read_area(0x83, 0, offset, 2)
                    value = snap7.util.get_int(data, 0)
                    return value
                if data_type == 'Bool':
                    bit = int(address.split('.')[1])
                    data = A01_Para.objPLC_tcp.read_area(0x83, 0, offset, 1)
                    value = snap7.util.get_bool(data, 0, bit)
                    return value
                if data_type == 'Real':
                    data = A01_Para.objPLC_tcp.read_area(0x83, 0, offset, 4)
                    value = snap7.util.get_real(data, 0)
                    value = str(format(value,".6f"))
                    return value
            if data_area == 'DB':
                db_num = int(db_num)
                offset = int(address.split('.')[0])
                if data_type == 'Int':
                    data = A01_Para.objPLC_tcp.read_area(0x84, db_num, offset, 2)
                    value = snap7.util.get_int(data, 0)
                    return value
                if data_type == 'Dint':
                    data = A01_Para.objPLC_tcp.read_area(0x84, db_num, offset, 4)
                    value = self.get_dint(data, 0)
                    return value
                if data_type == 'Bool':
                    bit = int(address.split('.')[1])
                    data = A01_Para.objPLC_tcp.read_area(0x84, db_num, offset, 1)
                    value = snap7.util.get_bool(data, 0, bit)
                    return value
                if data_type == 'Real':
                    data = A01_Para.objPLC_tcp.read_area(0x84, db_num, offset, 4)
                    value = snap7.util.get_real(data, 0)
                    value = str(format(value,".6f"))
                    return value
            if data_area == 'I':
                offset = int(address.split('.')[0])
                if data_type == 'Int':
                    data = A01_Para.objPLC_tcp.read_area(0x81, 0, offset, 2)
                    value = snap7.util.get_int(data, 0)
                    return value
                if data_type == 'Bool':
                    bit = int(address.split('.')[1])
                    data = A01_Para.objPLC_tcp.read_area(0x81, 0, offset, 1)
                    value = snap7.util.get_bool(data, 0, bit)
                    return value
                if data_type == 'Real':
                    data = A01_Para.objPLC_tcp.read_area(0x81, 0, offset, 4)
                    value = snap7.util.get_real(data, 0)
                    value = str(format(value,".6f"))
                    return value
            if data_area == 'Q':
                offset = int(address.split('.')[0])
                if data_type == 'Int':
                    data = A01_Para.objPLC_tcp.read_area(0x82, 0, offset, 2)
                    value = snap7.util.get_int(data, 0)
                    return value
                if data_type == 'Bool':
                    bit = int(address.split('.')[1])
                    data = A01_Para.objPLC_tcp.read_area(0x82, 0, offset, 1)
                    value = snap7.util.get_bool(data, 0, bit)
                    return value
                if data_type == 'Real':
                    data = A01_Para.objPLC_tcp.read_area(0x82, 0, offset, 4)
                    value = snap7.util.get_real(data, 0)
                    value = str(format(value,".6f"))
                    return value    
        except Exception as exc:            
            uL = UsAdmin_Log(Com_Para.ApplicationPath, "A01_N86TYV_PLC.single_signal_read error:"+repr(exc))
            uL.WriteLog()
            print('A01_N86TYV_PLC.single_signal_read signal read failed '+repr(exc))
            return False
    def StrtoByesarray(self,strdata):
        strarry = strdata.split()
        list = []
        for itm in strarry:
            list.append(itm)
        return bytearray(list)
    def send_data_plc(self,inputPLCAddress,inputPLCrack,inputPLCslot,inputDb_number,inputStart,inputData):
        pass